﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using HtmlAgilityPack;

namespace ProductCollector {
    public class CpapSearcher : ISiteSearcher {
        // O: term for search, 1: currentIndexPage; 2: NUmberProduct in page
        private const string SearchURL = "http://www.cpap.com/productSearch.php?query={0}#/0:{1}:{2}:{0}";
        private const string SITE_NAME = "http://www.cpap.com";
        public IList<Product> Search(SearchCriteria criteria) {
            criteria.NumOfProduct = 20;
            var web = new HtmlWeb();
            string url = SearchURL;
            url = string.Format(url, criteria.SearchValue, criteria.CurrentPageIndex, criteria.NumOfProduct);

            HtmlDocument doc = web.Load(url);
            var gridNode = doc.DocumentNode.SelectSingleNode("//div[contains(@id,'search-results')]/h1");
            var result = new List<Product>();
            if (gridNode != null) {
                int noOfProd = ParseNoOfSearch(gridNode.InnerText);
                if (noOfProd > 0) {

                    var tbody = doc.DocumentNode.SelectSingleNode("//table[contains(@id,'product-listing')]/tbody");

                    if (tbody != null) {
                        foreach (HtmlNode tr in tbody.ChildNodes) {
                            Product p = ParseProductFromTableRow(tr);
                            if (p != null) {
                                result.Add(p);
                            }
                        }
                    }
                }
            }
            return result;
        }
        private IList<Product> InternalSearch(SearchCriteria criteria) {
            var web = new HtmlWeb();
            string url = SearchURL;
            url = string.Format(url, criteria.SearchValue, criteria.CurrentPageIndex, criteria.NumOfProduct);

            HtmlDocument doc = web.Load(url);
            var gridNode = doc.DocumentNode.SelectSingleNode("//div[contains(@id,'search-results')]/h1");
            var result = new List<Product>();
            if (gridNode != null) {
                int noOfProd = ParseNoOfSearch(gridNode.InnerText);
                if (noOfProd > 0) {

                    var tbody = doc.DocumentNode.SelectSingleNode("//table[contains(@id,'product-listing')]/tbody");

                    if (tbody != null) {
                        foreach (HtmlNode tr in tbody.ChildNodes) {
                            Product p = ParseProductFromTableRow(tr);
                            if (p != null) {
                                result.Add(p);
                            }
                        }
                    }
                }
            }
            return result;
        }
        private Product ParseProductFromTableRow(HtmlNode tr) {
            if (tr == null) {
                return null;
            }
            Product p = new Product();
            //IMagethumb
            HtmlNode img = tr.SelectSingleNode("./td[contains(@class,'product-listing-pic')]/a/img");
            if (img != null) {
                p.ThumbImg = img.GetAttributeValue("src", string.Empty);
            }
            // Original Link
            HtmlNode anchor = tr.SelectSingleNode("./td[contains(@class,'product-listing-pic')]/a");
            if (anchor != null) {
                p.OriginalUrl = SITE_NAME + anchor.GetAttributeValue("href", SITE_NAME);
            }
            //Title
            HtmlNode title = tr.SelectSingleNode("./td[contains(@class,'product-info')]/a");
            if (title != null) {
                p.ProductName = title.InnerText;
            }
            HtmlNode man = tr.SelectSingleNode("./td[contains(@class,'product-info')]/a/em");
            if (man != null) {
                p.Manufacturer = man.InnerText;
            }
            // PRICE
            HtmlNode priceNode =
                tr.SelectSingleNode("./td[contains(@class,'product-price')]/strong[contains(@class,'our-price')]");
            if (priceNode != null) {
                p.Price = ParsePrice(priceNode.InnerText);
                p.FormattedPrice = priceNode.InnerText.Trim();
            }
            return p;
        }
        private int ParseNoOfSearch(string text) {
            var items = text.Split(' ');
            if (items.Count() > 2) {
                string noC = items[2];
                int no;
                if (int.TryParse(noC, out no)) {
                    return no;
                }
            }
            return 0;
        }
        private float ParsePrice(string price) {
            price = price.Trim();
            price = price.Remove(0);
            float p;
            if (float.TryParse(price, out p)) {
                return p;
            }
            return 0;
        }
        public int CountProduct(SearchCriteria criteria) {
            throw new NotImplementedException();
        }
    }
}
